package com.shanjupay.common.utilbak;

import org.apache.commons.lang.StringUtils;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.regex.Pattern;

/**
 * 日期工具类
 *
 * @author hKF13242
 * @version [版本号, 2009-7-6]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
public class DateUtil {
    /**
     * 标准时间格式
     */
    public static final String FORMAT_STANDARD = "yyyy-MM-dd HH:mm:ss";

    /**
     * 标准时间格式
     */
    public static final String FORMAT_STANDARD_MIN = "yyyy-MM-dd HH:mm";

    /**
     * 格式化类型:YYYY-MM-dd
     */
    public static final String FORMAT_YYYY_MM_DD = "yyyy-MM-dd";

    /**
     * 格式化类型:YYYYMMdd
     */
    public static final String FORMAT_YYYYMMDD = "yyyyMMdd";

    /**
     * 格式化类型:yyyyMMddHHmmss
     */
    public static final String FORMAT_YYYYMMDDHHMMSS = "yyyyMMddHHmmss";

    /**
     * 格式化类型:yyyy-MM-dd HH:mm:ss
     */
    public static final String FORMAT_YYYY_MM_DD_SECONDS = "yyyy-MM-dd HH:mm:ss";

    private static ThreadLocal<SimpleDateFormat> dateFormatLocal = new ThreadLocal<SimpleDateFormat>();


    /**
     * yyyyMMdd格式的 正则判断器
     */
    private static final Pattern YYYYMMDD_PATTERN = Pattern
            .compile("[1-9]{1}[0-9]{3}-((0?[1-9])|(1[0-2]))-((0?[1-9])|([1-2][0-9])|([3][0-1]))");

    /**
     * yyyy-MM-dd HH:mm:ss格式的 正则判断器
     */
    private static final Pattern YYYYMMDDHHMMSS_PATTERN = Pattern.compile(
            "[1-9]{1}[0-9]{3}-((0?[1-9])|(1[0-2]))-((0?[1-9])|([1-2][0-9])|([3][0-1]))\\s+(([0-1]?[0-9])|([2][0-3])):([0-5]?[0-9]):([0-5]?[0-9])");

    private static ThreadLocal<SimpleDateFormat> dateFormat = new ThreadLocal<SimpleDateFormat>();

    private DateUtil() {

    }

    /**
     * 得到当前时间的字符格式
     *
     * @return String
     * @see [类、类#方法、类#成员]
     */
    public static String getCurrentTime() {
        SimpleDateFormat standardFormate = getStandardFormate();

        return standardFormate.format(new Date());
    }

    public static String formatTime2Str(long ms) {
        int ss = 1000;
        int mi = ss * 60;
        int hh = mi * 60;
        int dd = hh * 24;

        long day = ms / dd;
        long hour = (ms - day * dd) / hh;
        long minute = (ms - day * dd - hour * hh) / mi;
        long second = (ms - day * dd - hour * hh - minute * mi) / ss;
        long milliSecond = ms - day * dd - hour * hh - minute * mi - second * ss;

        String strDay = day < 10 ? "0" + day : "" + day; //天  
        String strHour = hour < 10 ? "0" + hour : "" + hour;//小时  
        String strMinute = minute < 10 ? "0" + minute : "" + minute;//分钟  
        String strSecond = second < 10 ? "0" + second : "" + second;//秒  
        String strMilliSecond = milliSecond < 10 ? "0" + milliSecond : "" + milliSecond;//毫秒  
        strMilliSecond = milliSecond < 100 ? "0" + strMilliSecond : "" + strMilliSecond;
        return (strDay.equals("00") ? "" : (strDay + "天")) + (strHour.equals("00") ? "" : (strHour + "小时")) + strMinute + "分钟 " + strSecond + "秒";
    }

    /**
     * 得到当前日期
     *
     * @return
     * @description 得到当前日期
     * @author Leon
     * @date 2016年5月10日下午10:51:28
     */

    public static Date getCurrentDate() {
        //处理时间，建议用Calendar
        Calendar c = Calendar.getInstance();
        //设置当前时刻的时钟为0
        c.set(Calendar.HOUR_OF_DAY, 0);
        //设置当前时刻的分钟为0
        c.set(Calendar.MINUTE, 0);
        //设置当前时刻的秒钟为0
        c.set(Calendar.SECOND, 0);
        //设置当前的毫秒钟为0
        c.set(Calendar.MILLISECOND, 0);
        return c.getTime();
    }


    public static int getDay(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.get(Calendar.DAY_OF_WEEK) == 1 ? 7 : cal.get(Calendar.DAY_OF_WEEK) - 1;
    }

    /**
     * 计算两个日期之间相差的天数
     *
     * @param smdate 较小的时间
     * @param bdate  较大的时间
     * @return 相差天数
     * @throws ParseException
     */
    public static int daysBetween(Date smdate, Date bdate) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        smdate = sdf.parse(sdf.format(smdate));
        bdate = sdf.parse(sdf.format(bdate));
        Calendar cal = Calendar.getInstance();
        cal.setTime(smdate);
        long time1 = cal.getTimeInMillis();
        cal.setTime(bdate);
        long time2 = cal.getTimeInMillis();
        long between_days = (time2 - time1) / (1000 * 3600 * 24);

        return Integer.parseInt(String.valueOf(between_days));
    }

    /**
     * 计算两个日期之间相差的天数
     *
     * @param smdate 较小的时间
     * @param bdate  较大的时间
     * @return 相差时间
     * @throws ParseException
     */
    public static long timesBetween(Date smdate, Date bdate) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        smdate = sdf.parse(sdf.format(smdate));
        bdate = sdf.parse(sdf.format(bdate));
        Calendar cal = Calendar.getInstance();
        cal.setTime(smdate);
        long time1 = cal.getTimeInMillis();
        cal.setTime(bdate);
        long time2 = cal.getTimeInMillis();

        return time2 - time1;
    }

    /**
     * 字符串的日期格式的计算
     */
    public static int daysBetween(String smdate, String bdate) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();
        cal.setTime(sdf.parse(smdate));
        long time1 = cal.getTimeInMillis();
        cal.setTime(sdf.parse(bdate));
        long time2 = cal.getTimeInMillis();
        long between_days = (time2 - time1) / (1000 * 3600 * 24);

        return Integer.parseInt(String.valueOf(between_days));
    }

    /**
     * 得到本周周一
     *
     * @param date
     */
    public static Date getMondayOfThisWeek(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int day_of_week = c.get(Calendar.DAY_OF_WEEK) - 1;
        if (day_of_week == 0)
            day_of_week = 7;
        c.add(Calendar.DATE, -day_of_week + 1);
        return c.getTime();
    }

    public static String getMondayOfThisWeek(Date date, String format) {
        return DateUtil.format(getMondayOfThisWeek(date), format);
    }

    /**
     * 得到本周周日
     *
     * @param date
     */
    public static Date getSundayOfThisWeek(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int day_of_week = c.get(Calendar.DAY_OF_WEEK) - 1;
        if (day_of_week == 0)
            day_of_week = 7;
        c.add(Calendar.DATE, -day_of_week + 7);
        return c.getTime();
    }

    public static String getSundayOfThisWeek(Date date, String format) {
        return DateUtil.format(getSundayOfThisWeek(date), format);
    }

    public static String formatDte2DteByFormat(String date, String format1, String format2) {
        SimpleDateFormat format = new SimpleDateFormat(format1);
        Date d = null;
        try {
            d = format.parse(date);
            format = new SimpleDateFormat(format2);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return format.format(d);
    }

    /**
     * 得到当前时间
     *
     * @return Timestamp
     * @see [类、类#方法、类#成员]
     */
    public static Timestamp getCurrentDatetime() {
        return new Timestamp(System.currentTimeMillis());
    }

    /**
     * 格式化成系统常用日期格式：yyyyMMddHHmmss
     *
     * @param date date
     * @return String
     * @see [类、类#方法、类#成员]
     */
    public static String format(Date date) {
        if (date == null) {
            return null;
        }

        SimpleDateFormat standardFormate = getStandardFormate();
        return standardFormate.format(date);
    }

    /**
     * 获取标准日期格式
     *
     * @return SimpleDateFormat
     * @throws throws
     * @see [类、类#方法、类#成员]
     */
    public static SimpleDateFormat getStandardFormate() {
        if (null == dateFormatLocal.get()) {
            dateFormatLocal.set(new SimpleDateFormat(FORMAT_STANDARD));
        }
        return dateFormatLocal.get();
    }

    private static SimpleDateFormat getDateFormate(String formate) {
        return new SimpleDateFormat(formate);
    }

    /**
     * 格式化日期
     *
     * @param date      date
     * @param formatStr formatStr
     * @return String
     * @see [类、类#方法、类#成员]
     */
    public static String format(Date date, String formatStr) {
        if (date == null) {
            return null;
        }

        SimpleDateFormat sf = new SimpleDateFormat(formatStr);
        return sf.format(date);
    }

    /**
     * 判断两个日期是否为同年同月
     *
     * @param date1 date1
     * @param date2 date2
     * @return boolean
     * @see [类、类#方法、类#成员]
     */
    public static boolean isSameYYYYMM(Date date1, Date date2) {
        Calendar c1 = Calendar.getInstance();
        c1.setTime(date1);

        Calendar c2 = Calendar.getInstance();
        c2.setTime(date2);

        return (c1.get(Calendar.YEAR) == c2.get(Calendar.YEAR)) && (c1.get(Calendar.MONTH) == c2.get(Calendar.MONTH));
    }

    /**
     * 判断两个日期是否为同年同月
     *
     * @param date1 date1
     * @param date2 date2
     * @return boolean
     * @see [类、类#方法、类#成员]
     */
    public static boolean isSameYYYYMMDD(Date date1, Date date2) {
        Calendar c1 = Calendar.getInstance();
        c1.setTime(date1);

        Calendar c2 = Calendar.getInstance();
        c2.setTime(date2);

        return (c1.get(Calendar.YEAR) == c2.get(Calendar.YEAR)) && (c1.get(Calendar.MONTH) == c2.get(Calendar.MONTH))
                && (c1.get(Calendar.DAY_OF_MONTH) == c2.get(Calendar.DAY_OF_MONTH));
    }

    /**
     * 把字符串格式化日期
     *
     * @param dateStr  dateStr
     * @param formater formater
     * @return Date
     * @see [类、类#方法、类#成员]
     */
    public static Date formdate(String dateStr, String formater) {
        formater = (null == formater) ? FORMAT_STANDARD : formater;
        DateFormat formatter = new SimpleDateFormat(formater);
        Date date = null;
        try {
            date = formatter.parse(dateStr);
        } catch (ParseException e) {
            //logger.error("ParseException error, Exception = " + e);
        }
        return date;
    }

    /**
     * 本年度第几周
     *
     * @param date
     * @return int
     * @throws throws
     */
    public static int getWeekNumOfYear(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.setFirstDayOfWeek(Calendar.MONDAY);
        return c.get(Calendar.WEEK_OF_YEAR);
    }

    /**
     * 判断一个字符串是否满足给定的日期格式<一句话功能简述> <功能详细描述>
     *
     * @param str        String
     * @param dateFormat dateFormat
     * @return boolean dateFormat
     * @see [类、类#方法、类#成员]
     */
    public static boolean judgeDateFormat(String str, String dateFormat) {
        if (str != null) {
            SimpleDateFormat formatter = new SimpleDateFormat(dateFormat);
            formatter.setLenient(false);

            try {
                formatter.format(formatter.parse(str));
            } catch (Exception e) {
                return false;
            }

            return true;
        }

        return false;
    }

    /**
     * getOffsetNewDate
     *
     * @param date   date
     * @param offset offset
     * @return Date
     * @see [类、类#方法、类#成员]
     */
    public static Date getOffsetNewDate(Date date, int offset) {
        GregorianCalendar gc = new GregorianCalendar();
        gc.setTime(date);
        gc.add(Calendar.DAY_OF_MONTH, offset);
        Date newDate = gc.getTime();
        return newDate;
    }

    /**
     * date转timestamp类型 maintian changcheng author changcheng edit changcheng
     */
    public static Timestamp convertDate2TStamp(Date date) {
        if (null == date) {
            return null;
        }
        return new Timestamp(date.getTime());
    }

    /**
     * 以分钟为单位对时间进行调整
     *
     * @param time   要调整的时间
     * @param minite 增加的分钟数
     * @return String 调整后的时间
     */
    public static String addMinute(String time, int minite) {
        if (StringUtils.isEmpty(time)) {
            return "";
        }
        Calendar calendar = Calendar.getInstance();
        DateFormat dateFormat = new SimpleDateFormat(FORMAT_STANDARD);
        Date date = null;
        try {
            date = dateFormat.parse(time);
        } catch (ParseException e) {
            return "";
        }
        calendar.setTimeInMillis(date.getTime());
        calendar.add(Calendar.MINUTE, minite);
        return dateFormat.format(calendar.getTime());
    }

    /**
     * 以分钟为单位对时间进行调整
     *
     * @param minite 增加的分钟数
     * @return String 调整后的时间
     */
    public static Date addMinute(Date requestTime, int minite) {
        if (null == requestTime) {
            return null;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(requestTime.getTime());
        calendar.add(Calendar.MINUTE, minite);
        return calendar.getTime();
    }

    /**
     * 获取几天前的日期
     *
     * @param days
     * @return Date
     * @throws throws
     * @see [类、类#方法、类#成员]
     */
    public static Date getBeforeDateInDay(int days) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, -days);
        return calendar.getTime();
    }

    /**
     * 得到当前时间的字符格式
     *
     * @param formate
     * @return String [返回类型说明]
     * @see [类、类#方法、类#成员]
     */
    public static String getCurrentTime(String formate) {
        SimpleDateFormat standardFormate = getDateFormate(formate);
        return standardFormate.format(new Date());
    }

    /**
     * <一句话功能简述>验证日期 字符串的有效性 格式为:yyyy-MM-dd HH:mm:ss <功能详细描述>
     *
     * @param dateStr
     * @return boolean
     * @see [类、类#方法、类#成员]
     */
    public static boolean validateYYYYMMDDHHMMSSDateStr(String dateStr) {
        if (StringUtils.isEmpty(dateStr) || (!YYYYMMDDHHMMSS_PATTERN.matcher(dateStr).matches())) {
            return false;
        }

        return true;
    }

    /**
     * 验证日期格式是否为yyyy-MM-dd样式
     *
     * @param date Date
     * @return String
     * @throws ParseException
     * @see [类、类#方法、类#成员]
     */
    public static Boolean isYYYYMMDD(String date) {
        if (date == null) {
            return false;
        }

        if (YYYYMMDD_PATTERN.matcher(date).matches()) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 格式化为 Timestamp
     *
     * @param dateStr  String
     * @param formater String
     * @return Timestamp
     * @see [类、类#方法、类#成员]
     */
    public static Timestamp formTimestamp(String dateStr, String formater) {
        return new Timestamp(formdate(dateStr, formater).getTime());
    }

    /**
     * 传入时间是否在当前时间之前
     *
     * @return boolean [返回类型说明]
     * @see [类、类#方法、类#成员]
     */
    public static boolean isBeforeNowTime(Date compareTime) {
        Date nowTime = new Date();
        return nowTime.before(compareTime);
    }

    /**
     * 转换时间字符串为日期 <功能详细描述>格式为yyyy-MM-dd
     *
     * @param date      Date
     * @param formatStr String 日期转换类型
     * @return String
     * @throws ParseException
     * @see [类、类#方法、类#成员]
     */
    public static Date parseNormalDate(String date, String formatStr) throws Exception {
        if (date == null) {
            return null;
        }
        formatStr = StringUtils.isBlank(formatStr) ? FORMAT_YYYY_MM_DD : formatStr;
        if (YYYYMMDD_PATTERN.matcher(date).matches()) {
            SimpleDateFormat sdf = getSimpleDateFormat(formatStr);
            sdf.setLenient(false);
            return sdf.parse(date);
        } else {
            throw new Exception("日期格式不正确");
        }
    }

    /**
     * 从ThreadLocal中获取日期格式器
     *
     * @param format
     * @return SimpleDateFormat [返回类型说明]
     * @throws throws [违例类型] [违例说明]
     * @see [类、类#方法、类#成员]
     */
    private static SimpleDateFormat getSimpleDateFormat(String format) {
        SimpleDateFormat sdf = dateFormat.get();
        if (null != sdf) {
            if (StringUtils.isNotEmpty(format)) {
                sdf.applyPattern(format);
            }
            return sdf;
        } else {
            if (StringUtils.isEmpty(format)) {
                format = FORMAT_YYYY_MM_DD_SECONDS;
            }
            sdf = new SimpleDateFormat(format);
            dateFormat.set(sdf);
        }
        return sdf;
    }

    /**
     * 传入时间是否是今天
     *
     * @return
     */
    public static boolean inDay(Date date) {
        Calendar c1 = Calendar.getInstance();
        c1.setTime(date);

        Calendar c2 = Calendar.getInstance();
        c2.setTime(new Date());

        return (c1.get(Calendar.YEAR) == c2.get(Calendar.YEAR)) && (c1.get(Calendar.MONTH) == c2.get(Calendar.MONTH))
                && (c1.get(Calendar.DATE) == c2.get(Calendar.DATE));
    }

    /**
     * 两个日期相减所得到的值 DateOne - DateTwo
     *
     * @param dateOne
     * @param dateTwo
     * @return 两个时间相减得到的时间
     */

    public static long dateSubtract(Date dateOne, Date dateTwo) {
        if (dateOne == null) {
            dateOne = new Date();
        }
        if (dateTwo == null) {
            dateTwo = new Date();
        }
        Calendar cOne = Calendar.getInstance();
        cOne.setTime(dateOne);

        Calendar cTwo = Calendar.getInstance();
        cTwo.setTime(dateTwo);

        return cOne.getTimeInMillis() - cTwo.getTimeInMillis();
    }

    public static int yearSbstract(Date dateOne, Date dateTwo) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(dateOne);
        int yearOne = cal.get(Calendar.YEAR);
        cal.setTime(dateTwo);
        int yearTwo = cal.get(Calendar.YEAR);
        return yearOne - yearTwo;
    }


    /**
     * 获取多少天前的日期
     *
     * @param day
     * @return
     */
    public static String getFrontDayDate(int day) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        cal.add(Calendar.DATE, -day);
        String date = format(cal.getTime(), "yyyy-MM-dd HH:mm:ss");
        return date;
    }

    public static String getWeekCounterByEventStartDate(String event_s_date, String dailyDate) {
        if (isSameWeek(event_s_date, dailyDate)) {
            return "1";
        }
        Calendar c_base = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        Calendar tempC = Calendar.getInstance();
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        int week = 0;
        try {
            c_base.setTime(df.parse(event_s_date));
            c2.setTime(df.parse(dailyDate));
            Long time1 = c2.getTimeInMillis();
            Long time2 = c_base.getTimeInMillis();
            Long dayDiffer = Math.abs(time1 - time2) / (1000 * 60 * 60 * 24);//毫秒*秒*分*小时
            if (dayDiffer.intValue() == 0) {
                week++;
                return "" + week;
            }
            int curTodayWeek = c_base.get(Calendar.DAY_OF_WEEK) - 1;
            int differIsWeek = 7 - curTodayWeek;
            tempC = (Calendar) c_base.clone();

            if (differIsWeek != 0) {
                week++;
            }
            if (differIsWeek != 7) {
                tempC.add(Calendar.DAY_OF_YEAR, differIsWeek);
            }
            time1 = c2.getTimeInMillis();
            time2 = tempC.getTimeInMillis();
            dayDiffer = Math.abs(time1 - time2) / (1000 * 60 * 60 * 24);//毫秒*秒*分*小时
            if (dayDiffer.intValue() == 1) {//差一天
                week++;
            } else if (dayDiffer.intValue() < 7) {
                week++;
            } else {
                DecimalFormat decimalFormat = new DecimalFormat("#.0");
                String dayNum = decimalFormat.format((double) dayDiffer.intValue() / 7);
                int day = Integer.parseInt(dayNum.substring(0, dayNum.indexOf(".")));
                week += day;
                int dec = Integer.parseInt(dayNum.substring(dayNum.indexOf(".") + 1, dayNum.length()));
                if (dec != 0) {
                    week++;
                }
            }
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
            return "";
        }
        return "" + week;
    }

    public static boolean isSameWeek(String date1, String date2) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Date d1 = null;
        Date d2 = null;
        try {
            d1 = format.parse(date1);
            d2 = format.parse(date2);
        } catch (Exception e) {
            e.printStackTrace();
        }
        Calendar cal1 = Calendar.getInstance();
        Calendar cal2 = Calendar.getInstance();
        cal1.setTime(d1);
        cal2.setTime(d2);

        int subYear = cal1.get(Calendar.YEAR) - cal2.get(Calendar.YEAR);
        int subMonth = (cal1.get(Calendar.MONTH) + 1) - (cal2.get(Calendar.MONTH) + 1);

        //同一年，同一月
        if (subYear == 0 && subMonth == 0) {
            int week1 = cal1.get(Calendar.WEEK_OF_MONTH);
            int week2 = cal2.get(Calendar.WEEK_OF_MONTH);
            int wd1 = cal1.get(Calendar.DAY_OF_WEEK);
            int wd2 = cal2.get(Calendar.DAY_OF_WEEK);
            if (wd1 == 1) {
                week1 -= 1;
            }
            if (wd2 == 1) {
                week2 -= 1;
            }
            return week1 == week2;
        }
        return false;
    }

    //目标时间是否在时间范围内
    public static boolean isContain(Date startDate, Date endDate, Date checkDate) {
        if (startDate.getTime() <= checkDate.getTime() && checkDate.getTime() <= endDate.getTime()) {
            return true;
        }
        return false;
    }

    public static String dateToWeek(String time){
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = format.parse(time);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Instant instant = date.toInstant();
        ZoneId zoneId = ZoneId.systemDefault();
        LocalDate localDate = instant.atZone(zoneId).toLocalDate();
        DayOfWeek day = localDate.getDayOfWeek();
        String weekDay = "";

        switch (day) {
            case MONDAY:
                weekDay = "星期一";
                break;
            case FRIDAY:
                weekDay = "星期五";
                break;
            case SATURDAY:
                weekDay = "星期六";
                break;
            case SUNDAY:
                weekDay = "星期日";
                break;
            case THURSDAY:
                weekDay = "星期四";
                break;
            case TUESDAY:
                weekDay = "星期二";
                break;
            case WEDNESDAY:
                weekDay = "星期三";
                break;
        }
        return weekDay;
    }

    /**

  * 获取指定日期下个月的第一天
  * @param dateStr
  * @param format
  * @return
  */
 public static String getFirstDayOfNextMonth(String dateStr,String format){
     SimpleDateFormat sdf = new SimpleDateFormat(format);
     try {
        Date date = sdf.parse(dateStr);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH,1);
        calendar.add(Calendar.MONTH, 1);
        return sdf.format(calendar.getTime());
     } catch (ParseException e) {
        e.printStackTrace();
     }
     return null;
 }

    public static void main(String[] args) {
        String dateStr = getFirstDayOfNextMonth("2020-12-08 15:40:00","yyyy-MM-dd");
        Date date = formdate(dateStr+" 00:00:00","yyyy-MM-dd HH:mm:ss");
        System.out.println(format(date,"yyyy-MM-dd HH:mm:ss"));
    }
}
